package com.finder.main;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;

public class MainClass {

	List<String> extensions = null;

	public MainClass() throws Exception {

		String[] ext = new String[] { "ear", "jar", "war", "zip" };
		extensions = Arrays.asList(ext);

		File file = new File("D:\\Downloads\\AppOrders.ear");
		FileInputStream fis = new FileInputStream(file);

		open("D:\\JARS", file, fis);

	}

	public Map<String, List<Class<?>>> loadAndScanJar(File jarFile) throws ClassNotFoundException, ZipException, IOException {

		// Load the jar file into the JVM
		// You can remove this if the jar file already loaded.
		// super.addURL(jarFile.toURI().toURL());

		Map<String, List<Class<?>>> classes = new HashMap<String, List<Class<?>>>();
		// List<Class<?>> interfaces = new ArrayList<Class<?>>();
		// List<Class<?>> clazzes = new ArrayList<Class<?>>();
		// List<Class<?>> enums = new ArrayList<Class<?>>();
		// List<Class<?>> annotations = new ArrayList<Class<?>>();
		// classes.put("interfaces", interfaces);
		// classes.put("classes", clazzes);
		// classes.put("annotations", annotations);
		// classes.put("enums", enums);
		// int count = 0;
		// JarFile jar = new JarFile(jarFile);
		// Enumeration<? extends JarEntry> enumeration = jar.entries();
		// while (enumeration.hasMoreElements()) {
		// ZipEntry zipEntry = enumeration.nextElement();
		// if (zipEntry.getName().endsWith(".class")) {
		// String className = zipEntry.getName();
		// className = className.replace(".class", "").replace("/", ".");
		// Class<?> clazz = this.loadClass(className);
		// try {
		// if (clazz.isInterface()) {
		// interfaces.add(clazz);
		// } else if (clazz.isAnnotation()) {
		// annotations.add(clazz);
		// } else if (clazz.isEnum()) {
		// enums.add(clazz);
		// } else {
		// clazzes.add(clazz);
		// }
		// count++;
		// } catch (ClassCastException e) {
		// }
		// }
		// }
		// System.out.println("Total: " + count);
		return classes;
	}

	public void prueba(String jarFileName) {

		try {
			// a jar file
			// String jarFileName;
			// jarFileName = args[0];
			// File file = new File(jarFileName);
			System.out.println("================================================================");

			JarFile jarFile = new JarFile(jarFileName);

			System.out.println("Manifest Name: " + JarFile.MANIFEST_NAME);

			Enumeration<JarEntry> jarContents = jarFile.entries();
			while (jarContents.hasMoreElements()) {
				ZipEntry zipVersion = (ZipEntry) jarContents.nextElement();

				System.out.println("ZipFile: " + zipVersion + ", " + "zipEntry Size = " + zipVersion.getSize());
			}
			System.out.println("================================================================");

			// extract jar file contents and put them into the hashtable.
			FileInputStream fileStream = new FileInputStream(jarFileName);
			BufferedInputStream buffStream = new BufferedInputStream(fileStream);
			JarInputStream zipStream = new JarInputStream(buffStream);
			ZipEntry zipEntry = null;

			while ((zipEntry = zipStream.getNextEntry()) != null) {
				System.out.println("zipEntry Name = " + zipEntry.getName() + ", " + "zipEntry Size = " + zipEntry.getSize());
			}
			zipStream.close();
			System.out.println("================================================================");

		} catch (NullPointerException e) {
			System.out.println("done.");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void open(String destDir, File file, InputStream is) throws Exception {

		if (file.isFile()) {
			String onlyFileName = file.getName();
			File onlyParent = file.getParentFile();
			int index = onlyFileName.lastIndexOf('.');
			if (index != -1) {
				String extension = onlyFileName.substring(index + 1).toLowerCase();
				if (extensions.contains(extension)) {
					ZipInputStream jar = new ZipInputStream(is);
					byte[] buff = new byte[1024];
					ZipEntry entryFile = null;
					while ((entryFile = jar.getNextEntry()) != null) {
						String fileEntryName = destDir + File.separator + onlyFileName + File.separator + entryFile.getName();
						File fileEntry = new File(fileEntryName);
						File parent = fileEntry.getParentFile();
						if(!parent.exists()){
							parent.mkdirs();
						}
						PipedOutputStream fos = new PipedOutputStream();
						PipedInputStream pin1 = new PipedInputStream();
						fos.connect(pin1);
						int l = 0;
						while ((l = jar.read(buff)) > 0) {
							fos.write(buff, 0, l);
						}
						fos.close();
						open(destDir, fileEntry, pin1);
					}
					jar.close();
				}
			} else {
				FileOutputStream fos = new FileOutputStream(file);
				while (is.available() > 0) {
					fos.write(is.read());
				}
				fos.close();
				is.close();
			}
		} else if (file.isDirectory()) {
			file.mkdirs();
		}
	}

	public static void main(String[] args) throws Exception {
		new MainClass();
	}

}
